#pragma once

#ifndef EventScheme_h
#define EventScheme_h

#pragma warning (disable : 4996)
#pragma warning (disable : 4251)

#include <list>
#include <string>

#include "Export.h"
#include "MQOBJECT.h"

class INFOBUS_API Trace
{
public:
  Trace(const char* pszClass, const char* pszMethod, const char* pszDirection);
  Trace(const Trace * pOther);
  ~Trace();
  const char* getClass() const;
  const char* getMethod() const;
  const char* getDirection() const;
private:
  char m_szClass[256];
  char m_szMethod[256];
  char m_szDirection[50];
};

class INFOBUS_API EventScheme : public MessageQueueObject
{
public:
  EventScheme()
    : m_lSeq(0), m_lSeqsize(0), m_lMsgId(0), m_lRefMsgId(0), m_pszXml(NULL), m_lLineNo(0)
  {
    memset(m_szEventName, 0, sizeof m_szEventName);
    memset(m_szEvenType, 0, sizeof m_szEvenType);
    memset(m_szEventSeverity, 0, sizeof m_szEventSeverity);
    memset(m_szMethodName, 0, sizeof m_szMethodName);
    memset(m_szDirection, 0, sizeof m_szDirection);
    memset(m_szSeqName, 0, sizeof m_szSeqName);
    memset(m_szExec, 0, sizeof m_szExec);
    memset(m_szClassName, 0, sizeof m_szClassName);   
    memset(m_szFileName, 0, sizeof m_szFileName);
    memset(m_szEventCategory, 0, sizeof m_szEventCategory);

    m_liPattern.clear();
    m_liTrace.clear();
  }
  EventScheme(const EventScheme * pOther)
    : m_lSeq(0), m_lSeqsize(0), m_lMsgId(0), m_lRefMsgId(0), m_pszXml(NULL), m_lLineNo(0)
  {
    memset(m_szEventName, 0, sizeof m_szEventName);
    memset(m_szEvenType, 0, sizeof m_szEvenType);
    memset(m_szEventSeverity, 0, sizeof m_szEventSeverity);
    memset(m_szMethodName, 0, sizeof m_szMethodName);
    memset(m_szDirection, 0, sizeof m_szDirection);
    memset(m_szSeqName, 0, sizeof m_szSeqName);
    memset(m_szExec, 0, sizeof m_szExec);
    memset(m_szClassName, 0, sizeof m_szClassName);
    memset(m_szFileName, 0, sizeof m_szFileName);
    memset(m_szEventCategory, 0, sizeof m_szEventCategory);

    m_lSeq = pOther->m_lSeq;
    m_lSeqsize = pOther->m_lSeqsize;
    m_lMsgId = pOther->m_lMsgId;
    m_lRefMsgId = pOther->m_lRefMsgId;

    if (pOther->m_szEventName) strncpy(m_szEventName, pOther->m_szEventName, sizeof m_szEventName-1);
    if (pOther->m_szEvenType) strncpy(m_szEvenType, pOther->m_szEvenType, sizeof m_szEvenType-1);
    if (pOther->m_szEventSeverity) strncpy(m_szEventSeverity, pOther->m_szEventSeverity, sizeof m_szEventSeverity-1);
    if (pOther->m_szMethodName) strncpy(m_szMethodName, pOther->m_szMethodName, sizeof m_szMethodName-1);
    if (pOther->m_szDirection) strncpy(m_szDirection, pOther->m_szDirection, sizeof m_szDirection-1);
    if (pOther->m_szSeqName) strncpy(m_szSeqName, pOther->m_szSeqName, sizeof m_szSeqName-1);
    if (pOther->m_szExec) strncpy(m_szExec, pOther->m_szExec, sizeof m_szExec-1);
    if (pOther->m_szEventCategory) strncpy(m_szEventCategory, pOther->m_szEventCategory, sizeof m_szEventCategory-1);

    m_liPattern.clear();

    std::list<std::string> li = pOther->m_liPattern;
    std::list<std::string>::iterator itePattern;
    for (itePattern = li.begin(); itePattern != li.end(); ++itePattern)
      m_liPattern.push_back(*itePattern);

    m_liTrace.clear();

    std::list<std::string> li2 = pOther->m_liTrace;
    std::list<std::string>::iterator iteTrace;
    for (iteTrace = li2.begin(); iteTrace != li2.end(); ++iteTrace)
      m_liTrace.push_back(*iteTrace);       
  }

  EventScheme(const char* szEventName, 
              const char* szEvenType, 
              const char* szEventSeverity, 
              const char* szMethodName, 
              const char* szDirection, 
              const char* szSeqName,
              long lSeq, 
              long lSeqsize)
    : m_lSeq(lSeq), m_lSeqsize(lSeqsize), m_lMsgId(0), m_lRefMsgId(0), m_pszXml(NULL), m_lLineNo(0)
  {
    memset(m_szEventName, 0, sizeof m_szEventName);
    memset(m_szEvenType, 0, sizeof m_szEvenType);
    memset(m_szEventSeverity, 0, sizeof m_szEventSeverity);
    memset(m_szMethodName, 0, sizeof m_szMethodName);
    memset(m_szDirection, 0, sizeof m_szDirection);
    memset(m_szSeqName, 0, sizeof m_szSeqName);
    memset(m_szExec, 0, sizeof m_szExec);
    memset(m_szClassName, 0, sizeof m_szClassName);
    memset(m_szFileName, 0, sizeof m_szFileName);
    memset(m_szEventCategory, 0, sizeof m_szEventCategory);

    if (szEventName) strncpy(m_szEventName, szEventName, sizeof m_szEventName-1);
    if (szEvenType) strncpy(m_szEvenType, szEvenType, sizeof m_szEvenType-1);
    if (szEventSeverity) strncpy(m_szEventSeverity, szEventSeverity, sizeof m_szEventSeverity-1);
    if (szMethodName) strncpy(m_szMethodName, szMethodName, sizeof m_szMethodName-1);
    if (szDirection) strncpy(m_szDirection, szDirection, sizeof m_szDirection-1);
    if (szSeqName) strncpy(m_szSeqName, szSeqName, sizeof m_szSeqName-1);

    m_liPattern.clear();
    m_liTrace.clear();
  }

  bool isValid()
  {
    if (!strcmp("", m_szExec) ||
        !strcmp("", m_szEventName) ||
        !strcmp("", m_szSeqName)) {
      return false;
    } else {
      return true;
    }
  }

  const char* toXml();

  const char* getExecutable() { return m_szExec; }
  const char* getEventName() { return m_szEventName; }
  const char* getEventType() { return m_szEvenType; }
  const char* getEventSeverity() { return m_szEventSeverity; }
  const char* getMethodName() { return m_szMethodName; }
  const char* getDirection() { return m_szDirection; }
  const char* getSeqName() { return m_szSeqName; }
  const char* getClassName() { return m_szClassName; }
  const char* getFileName() { return m_szFileName; }
  const char* getCategory() { return m_szEventCategory; }

  long getMessageId() { return m_lMsgId; }
  long getSequence() { return m_lSeq; }
  long getSequenceSize() { return m_lSeqsize; }
  long getRefMessageId() { return m_lRefMsgId; }
  long getProcessId() { return m_lProcessId; }
  long getThreadId() { return m_lThreadId; }
  long getLineNo() { return m_lLineNo; }

  void setMetadata(const char* szEventName, const char* szEvenType, const char* szEventSeverity, const char* szSeqName, long lSeq, long lSeqSize)
  {
    memset(m_szEventName, 0, sizeof m_szEventName);
    memset(m_szEvenType, 0, sizeof m_szEvenType);
    memset(m_szEventSeverity, 0, sizeof m_szEventSeverity);
    memset(m_szSeqName, 0, sizeof m_szSeqName);

    if (szEventName) strncpy(m_szEventName, szEventName, sizeof m_szEventName -1);
    if (szEvenType) strncpy(m_szEvenType, szEvenType, sizeof m_szEvenType -1);
    if (szEventSeverity) strncpy(m_szEventSeverity, szEventSeverity, sizeof m_szEventSeverity -1);
    if (szSeqName) strncpy(m_szSeqName, szSeqName, sizeof m_szSeqName-1);

    m_lSeq = lSeq;
    m_lSeqsize = lSeqSize;
  }
  void setCategory(const char* szEventCategory) 
  {
    memset(m_szEventCategory, 0, sizeof m_szEventCategory);
    if (szEventCategory) strncpy(m_szEventCategory, szEventCategory, sizeof m_szEventCategory -1);
  }
  void setClassName(const char* szClassName) 
  { 
    if (szClassName) strncpy(m_szClassName, szClassName, sizeof m_szClassName -1);
  }
  void setMethodName(const char* szMethodName) 
  { 
    if (szMethodName) strncpy(m_szMethodName, szMethodName, sizeof m_szMethodName -1);
  }
  void setDirection(const char* szDirection) 
  { 
    if (szDirection) strncpy(m_szDirection, szDirection, sizeof m_szDirection -1);
  }
  void setExecutable(const char* szExecutable)
  {
    if (szExecutable) strncpy(m_szExec, szExecutable, sizeof m_szExec -1);
  }
  void setMessageId(const char* szMsgId)
  {
    long l = atol(szMsgId);
    if (0 < l) m_lMsgId = l;
  }
  void setRefMessageId(const char* szRefMsgId)
  {
    long l = atol(szRefMsgId);
    if (0 < l) m_lRefMsgId = l;
  }
  void setRefMessageId(long lRefMsgId)
  {
    m_lRefMsgId = lRefMsgId;
  }
  void addTrace(std::string s)
  {
    m_liTrace.push_back(s);
  }
  void addPattern(std::string s)
  {
    m_liPattern.push_back(s);
  }
  void setProcessId(long lProcessId)
  {
    m_lProcessId = lProcessId;
  }
  void setThreadId(long lThreadId)
  {
    m_lThreadId = lThreadId;
  }
  void setFileName(const char* pszFileName)
  {
    memset(m_szFileName, 0, sizeof m_szFileName);
    if (pszFileName) strncpy(m_szFileName, pszFileName, sizeof m_szFileName-1);
  }
  void setLineNo(long lLineNo)
  {
    m_lLineNo = lLineNo;
  }
private:
  char m_szExec[256+1];
  char m_szEventName[256+1];
  char m_szEvenType[50+1];
  char m_szEventSeverity[50+1];
  char m_szEventCategory[256+1];
  long m_lSeq;
  long m_lSeqsize;
  long m_lMsgId;
  long m_lRefMsgId;
  char m_szSeqName[50+1];
  char m_szMethodName[256+1];
  char m_szDirection[50+1];
  char m_szClassName[256+1];
  long m_lProcessId;
  long m_lThreadId;
  char m_szFileName[256+1];
  long m_lLineNo;
  char* m_pszXml;

  std::list<std::string> m_liPattern;
  std::list<std::string> m_liTrace;

};



#endif
